package com.sun.sign.login;

import com.sun.sign.context.DefaultContextHolder;
import com.sun.sign.dao.ApplicationSessionContext;
import com.sun.sign.dao.SignResult;
import com.sun.sign.enums.SignErrorEnum;
import com.sun.sign.exception.SignProcessFailException;
import com.sun.sign.token.DefaultTokenHelper;
import lombok.extern.slf4j.Slf4j;


/**
 * @author Jay
 * @version v1.0
 * @description 默认的实现登录的类
 * @date 2018-03-02 10:53
 */
@Slf4j
public abstract class DefaultSignFactoryBean<S extends ApplicationSessionContext> extends AbstractSignFactoryBean {

    public DefaultContextHolder<S> defaultContextHolder;

    public DefaultTokenHelper<S> defaultTokenHelper;

    /**
     * 构造器
     *
     * @param defaultContextHolder
     * @param defaultTokenHelper
     */
    public DefaultSignFactoryBean(DefaultContextHolder defaultContextHolder, DefaultTokenHelper defaultTokenHelper) {
        this.defaultContextHolder = defaultContextHolder;
        this.defaultTokenHelper = defaultTokenHelper;
    }

    /**
     * 子类必须实现
     *
     * @see AbstractSignFactoryBean#executeLogin(String, String, Boolean)
     *
     * @param userName
     * @param password
     * @param isSingleLogin
     * @return
     */
    @Override
    public SignResult doLogin(String userName, String password, Boolean isSingleLogin) {
        return super.executeLogin(userName, password, isSingleLogin);
    }

    /**
     * 抽象方法子类必须实现，将token等信息存入redis
     *
     * @param userName
     * @return
     */
    @Override
    public String saveTokenToRedis(String userName) {
        return defaultTokenHelper.saveUserToRedis(this.getDataForSaveToRedis(userName));
    }

    /**
     * 如果登录，则踢出,不允许同时登录一个账号
     *
     * @param userName
     */
    @Override
    public void clearSession(String userName) {
        Integer id = this.getUserIdByUserName(userName);
        if (id == null) {
            throw new SignProcessFailException(SignErrorEnum.BNS_CHK_ERROR.getCode(), "userId不能为空");
        }
        if (defaultTokenHelper.isLogin(id)) {
            // 清除id对应的缓存信息
            defaultTokenHelper.cleanRedisSessionById(id);
        }
    }

    /**
     * 获取存入redis的信息的业务session对象
     *
     * @param userName
     * @return
     */
    private S getDataForSaveToRedis(String userName) {
        return defaultContextHolder.doSetSessionContext(userName);
    }

    /*=============================================abstract method============================================*/

    /**
     * 根据userName获取userId
     *
     * @param userName
     * @return
     */
    public abstract Integer getUserIdByUserName(String userName);

}
